import hbData from "@/utils/socket/heartBeatData.js"
import message from "@/utils/socket/Message.js"
import * as WS from "@/core/constant/WebSocketEvent.js"
import {REFERSH_TRAVEL_TIMER} from "@/core/constant/event.js"
import { app } from "@/main.js"
import {checkRole} from "@/core/app.js"

export default class Socket{
	 constructor(){
		this.baseUrl = ""
		this.ws = null
		this.cacheMessages = []
		this.hearbeatTimer = 0 
		this.receiverTimer = 0
		this.reconnectTimer = 0
		this.emitReconnectTimer = 0
		
		this.messageCallback = null
		this.onOpenCallback = null
		
		this.heartBeatStatus = false
		this.heartBeatCallback = null
		this.message = message
	}
	
	static instance = null
	
	static get Instance(){
		if(this.instance === null){
			this.instance = new Socket()
		}
		return this.instance
	}
	
	init(url){
		if(!url){
			return null
		}
		this.ws = uni.connectSocket({
			url,
			multiple:true,
			success:(res) => {
				console.log(url+'连接成功')
			},
			error:(err) => {
				console.log(url+"连接失败")
				console.log(err)
			}
		})
		this._bindListeners()
	}
	

	/**
	 * 用于刷新页面的数据的回调函数
	 * @param {Object} callback
	 */
	regHeartBeatCallback(callback){
		this.heartBeatCallback = callback
	}
	
	startHeartBeat(value){
		if(this.heartBeatStatus){
			this.heartBeat()
			return
		}
		this.message.role = checkRole()
		this.message.data = hbData
		this.message.data.userId = value.userId
		this.message.data.volunteerId = value.volunteerId
		this.heartBeatStatus = true
		
		this.heartBeat()
	}
	
	heartBeat(data = null){
		this.clearHeartBeatTimer()
		this.hearbeatTimer = setTimeout(() => {
			this.message.data.refreshData(data)
			console.log(!!this.heartBeatCallback)
			this.heartBeatCallback && this.heartBeatCallback(this.message.data)
			this.sendMessage(JSON.stringify(this.message))

			this.receiverTimer = setTimeout(() => {
				console.log("心跳未回应")
			},1000*5)
		},1000*5)
	}
	
	clearHeartBeatTimer(){
		if(this.hearbeatTimer){
			clearTimeout(this.hearbeatTimer)
			this.hearbeatTimer = 0
		}
		
		if(this.receiverTimer){
			clearTimeout(this.receiverTimer)
			this.receiverTimer = 0
		}
	}
	
	closeHeartBeatData(){
		this.heartBeatStatus = false
		this.clearHeartBeatTimer()
		this.message.data = null
	}
	
	reconnect(){
		this.destroyed()
		if(this.reconnectTimer){
			clearTimeout(this.reconnectTimer)
			this.reconnectTimer = 0
		}
		if(this.emitReconnectTimer){
			clearTimeout(this.emitReconnectTimer)
			this.emitReconnectTimer = 0
		}
		
		this.reconnectTimer = setTimeout(() => {
			app.$store.dispatch("socket/openSocket")
			if(app.$store.getters.websocket.ws !== null){
				return
			}
			// 重连后主动触发响应请求
			this.emitReconnectTimer = setTimeout(() => {
				this.reconnect()
			},1000)
		},2000)
	}
	
	sendMessage(msg){
		if(!this.ws){
			this.cacheMessages.push(msg)
		}else{
			console.log("---sendMessage--",msg)
			this.ws.send({data:msg})
		}
	}
	
	
	close(){
		if(this.ws){
			console.log("ws关闭中")
			this.closeHeartBeatData()
			this.ws.close()
		}
	}
	
	destroyed(){
		if(this.ws){
			this.clearHeartBeatTimer()
			this._unbindListeners()
			if(this.ws){
				this.ws.close()
			}
		}
		this.ws = null
	}
	
	_bindListeners(){
		this.ws.onOpen(e =>{
			// 开启心跳
			console.log("连接建立")
			if(this.heartBeatStatus){
				this.startHeartBeat()
			}
			
			// 发送堆积的消息
			if(this.cacheMessages && this.cacheMessages.length){
				this.cacheMessages.forEach(msg => {
					this.sendMessage(msg)
				})
			}
		});
		
		this.ws.onMessage(e => {
			const message = JSON.parse(e.data.data)
			console.log("-------收到消息-------")
			console.log(message)
			switch(message.type){
				case "forthwith":
					if(typeof message.data === "string"){
						uni.$emit(message.data)
						break
					}
					if(message.data.content){
						uni.$emit(message.data.content,message.data)
					}else if(message.data.code){
						uni.$emit(WS.FORTHWITH_ASSIST_VERIFY,message.data.code)
					}
					break
				case "notice":
					uni.$emit(message.type,message.data)
					uni.$emit(REFERSH_TRAVEL_TIMER)
					break
				case "heartbeat":
					this.heartBeatStatus && this.heartBeat(message.data)
					break
			}	
		})
		
		this.ws.onError( e => {
			console.log(e)
			this.reconnect()
		});
		
		this.ws.onClose(() => {
			console.log("连接关闭中.......")
			this.ws = null
			this.reconnect()
		})
		
	}
	
	
	_unbindListeners(){
		this.ws.onOpen = null
		this.ws.onMessage = null
		this.ws.onError = null
	}
}
